package com.smart.mattress.account.controller;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.mongodb.gridfs.GridFSDBFile;
import com.smart.mattress.account.redis.RedisUtil;
import com.smart.mattress.account.server.FileStoreService;
import com.smart.mattress.account.server.UserInfoService;
import com.smart.mattress.common.model.account.UserInfo;
import com.smart.mattress.common.model.result.ResultData;


/**
 * 登录控制器
 * Created by rencong on 17/3/11.
 */
@RestController
@RequestMapping("/login")
public class LoginController {

    Logger logger = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    UserInfoService userInfoService;
    @Autowired
    FileStoreService fileStoreService;

	@Autowired
    private RedisUtil redisUtil = new RedisUtil();
    private UserInfo userInfo = new UserInfo();
    
    /**
     * 用户登录
     * @param email
     * @param password
     * @return 登录结果对象
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject login(@RequestParam String email, @RequestParam String password) {

        logger.info("login:email:{},passowrd:{}",email,password);

        return userInfoService.login(email, password);
        
    }


    /**
     * 用户注册
     * @return
     */
    @RequestMapping(value = "/register",method = RequestMethod.POST)
    @ResponseBody 
    public JSONObject register(@ModelAttribute("userInfo") UserInfo userInfo,@RequestParam("birth") String birth){
    	
    	logger.info("register: email:{},passowrd:{}",userInfo.toString());
    	
    	String birthday[] = birth.split("/");

    	JSONObject json = new JSONObject();
    	json.put("year", birthday[2]);
    	json.put("month", birthday[0]);
    	json.put("day", birthday[1]);
    	userInfo.setBirthDay(json);
    	
    	String flog = userInfoService.register(userInfo);
    	
    	switch (flog){
			case "repeat" : return ResultData.mobileResult(1002,"The mailbox already exists",null);
			case "fail" : return ResultData.mobileResult(1005,"Server error",null); 
			case "success" : 
				userInfoService.updateSuperAccount(userInfo.getEmail());
				return ResultData.mobileResult(1,"Registration Success",null);
			default : return ResultData.mobileResult(0,"Server error",null);
    	}
    	
    }
    
    @RequestMapping(value = "/getPic",method = RequestMethod.GET)
    @ResponseBody
    public void getPic(HttpServletRequest request,HttpServletResponse response){
    	String param = request.getParameter("user");
    	if(param == null){
    		return;
    	}
    	String fileName = param.substring(0,19);
    	GridFSDBFile file = fileStoreService.findByFileName(fileName);  
        OutputStream os = null; 
        InputStream in = null;
        byte[] file_byte = new byte[512];
        try {  
            os = response.getOutputStream(); 
            in = file.getInputStream();
            while(in.read(file_byte)!=-1){
            	os.write(file_byte); 
            }
            os.flush();  
        } catch (Exception e) {  
            e.printStackTrace();  
        } 
    }
    
    /**
     * 用户修改信息
     * @param userInfo
     * @return
     */
    @RequestMapping(value = "/modify",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject modify(@ModelAttribute("userInfo") UserInfo userInfo,
    						 @RequestParam String birth,
    						 @RequestParam String token,
    						 MultipartFile head,
    						 String web_image){
    	logger.info("change_email:{},change_time:{}",userInfo.getEmail(),System.currentTimeMillis());
    	
    	if(!redisUtil.exists(token)){
    		return ResultData.mobileResult(0,"Access Error",null);
    	}
    	
    	long u_userId = (Long) redisUtil.get(token);
    	UserInfo u_userInfo = (UserInfo) userInfoService.getInfoByToken(token,UserInfo.class,"UserInfo");
    	userInfo.setImage(u_userInfo.getImage());
    	String user_image = u_userInfo.getImage();
    	if(head!=null){
    		
    		//删除之前的头像
    		fileStoreService.deleteByFileName(String.valueOf(u_userInfo.getUserId()));
    		
    		InputStream image_file = null;
			try {
				image_file = head.getInputStream();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
    		fileStoreService.saveFile(String.valueOf(u_userInfo.getUserId()), 
    								  String.valueOf(u_userInfo.getUserId()), 
    								  image_file);
    		
    	}
    	if(web_image!=null && web_image != "" && !"null".equals(web_image)){
    		userInfo.setImage(web_image);
    	}
    	
    	logger.info("modify:userInfo:{}",userInfo.toString());
    	
    	String birthday[] = birth.split("/");

    	JSONObject json = new JSONObject();
    	json.put("year", birthday[2]);
    	json.put("month", birthday[0]);
    	json.put("day", birthday[1]);
    	userInfo.setBirthDay(json);
    	
    	boolean flog = userInfoService.modify(userInfo);
    	
    	if(flog){
    		return ResultData.mobileResult(1,"Successfully modified",null); 
    	}else{
    		return ResultData.mobileResult(3005,"Server error.Failed to modify",null); 
    	}
    	
    }
    
    
    /**
     * 忘记密码
     * @param email
     * @return
     */
    @RequestMapping(value = "/forget",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject forget(@RequestParam String email ){
    	
    	logger.info("forget:email:{}",email);
    	
    	HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest(); 
    	
    	boolean flog = userInfoService.forget(email,req);
    	
    	if(flog){
    		return ResultData.mobileResult(1,"Sent Successfully",null);
    	}else{
    		return ResultData.mobileResult(1001,"User does not exist",null);
    	}
    	 
    }
    
    /**
     * 验证所发验证码的准确性
     * @param verifi
     * @return
     */
    @RequestMapping(value = "/verifi",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject checkVerifi(@RequestParam String email,@RequestParam String verifi){
    	
    	logger.info("checkVerifi:email:{},verifi:{}",email,verifi);
    	
    	if(!redisUtil.exists(email)){
    		return ResultData.mobileResult(1008,"verification is expired",null);
    	}
    	
    	//判断是否达到验证上限，一次发送，最大验证三次
    	int number = (int) redisUtil.get(email+"count_num");
    	if(number>=3){
    		redisUtil.remove(email);//超过三次之后清除验证信息
    		redisUtil.remove(email+"count_num");
    		return ResultData.mobileResult(1007,"Too many verification times",null);
    	}
    	String veifiCode = (String) redisUtil.get(email);
    	
    	//验证次数+1
    	number += 1;
    	redisUtil.set(email+"count_num",number);
		
    	if(verifi.equals(veifiCode)){
    		return ResultData.mobileResult(1,"Verification passed",null);
    	}else{
    		return ResultData.mobileResult(1006,"Validation failed",null);
    	}
    }
    
    /**
     * 修改密码，有两种情况:</br>
     * 忘记密码，通过email修改
     * 正常修改密码，通过token
     * @param password
     * @param email
     * @param token
     * @return
     */
    @RequestMapping(value = "/modifyPwd",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject modifyPwd(@RequestParam String password,
								@RequestParam(required = false) String email,
								@RequestParam(required = false) String token){

		password = password.trim();

    	logger.info("modifyPwd:password:{},email:{},token:{}", password, email, token);
    	
    	userInfo.setPassword(password);
    	if(email != null){
    		userInfo.setEmail(email);
    	}else{
    		userInfo.setUserId( (long)redisUtil.get(token) );
    	}
    	
    	boolean flog = userInfoService.modifyPwd(userInfo);
    	
    	if(flog){
    		return ResultData.mobileResult(1,"Successfully modified",null); 
    	}else{
    		return ResultData.mobileResult(3005,"Server error.Failed to modify",null); 
    	}
    }
    
    
    /**
     * 用户退出
     * @param token
     * @return
     */
    @RequestMapping(value = "/logout",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject logout(@RequestParam String token){
    	
    	redisUtil.remove(token);
    	
    	return ResultData.mobileResult(1,"Logout Successfully",null);
    }
    
    /**
     * 获取当前用户的一些基础信息，如firstName等
     * @param token
     * @return
     */
    @RequestMapping(value = "/getInfo",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject getInfo(@RequestParam String token){
    	
    	userInfo = userInfoService.getInfo(token);
    	
    	return ResultData.mobileResult(1,"Logout Successfully",JSONObject.toJSON(userInfo));
    }
    
    /**
     * 检测token是否失效
     * @param token
     * @return
     */
    @RequestMapping(value = "/checkToken",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject checkToken(@RequestParam String token){
    	
    	logger.info("check: token{}",token);
    	
    	boolean flog = redisUtil.exists(token);
    	
    	if(flog){
    		return ResultData.mobileResult(1,"Verification passed",null);
    	}else{
    		return ResultData.mobileResult(1006,"Validation failed",null);
    	}
    }
    
    /**
     * 根据email查询对应的用户
     * @param email
     * @return
     */
    @RequestMapping(value = "/query",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject queryUser(@RequestParam String email){
    	//先判断查询对象是否存在
    	long flog = userInfoService.checkExist(email, UserInfo.class,"UserInfo");
    	if(flog == 0){
    		return ResultData.mobileResult(1001,"User does not exist",null);
    	}
    	//查询信息
    	UserInfo ret = userInfoService.queryUser(email);
    	if(ret == null){
    		return ResultData.mobileResult(1001,"Failed to Query",null);
    	}else{
    		JSONObject data = new JSONObject();
    		data.put("email", ret.getEmail());
    		data.put("name",ret.getFirstName()+" "+(ret.getMiddleName() == null?"":(ret.getMiddleName()+" "))+ret.getLastName());
    		data.put("image", ret.getImage());
    		data.put("gender", ret.getGender());
    		return ResultData.mobileResult(1,"Successfully Query",data);
    	}
    }
    
    /**
     * 发出申请
     * @param token
     * @param email
     * @return
     */
    @RequestMapping(value = "/apply",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject applyConcern(@RequestParam String token,@RequestParam String email){
    	
    	String info = userInfoService.applyConcern(token, email);
    	
    	switch (info){
    		case "noUser" : return ResultData.mobileResult(1001,"User does not exist",null);
    		case "repeat" : return ResultData.mobileResult(1002,"Has applied for the user",null);
    		case "self" : return ResultData.mobileResult(1003,"Can not Concern YourSelf",null);
    		case "fail" : return ResultData.mobileResult(0,"Server error.Failed to Apply",null); 
    		case "success" : return ResultData.mobileResult(1,"Apply Success",null);
    		default : return ResultData.mobileResult(0,"Server error",null);
    	}
    	
    }
    
    /**
     * 处理申请
     * @param token
     * @param email
     * @param handle
     * @return
     */
    @RequestMapping(value = "/handle",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject handleConcern(@RequestParam String token,@RequestParam String email,@RequestParam String handle){
    	
    	//handle:agree同意，disagree不同意申请
    	
    	String flog = userInfoService.handleConcern(token, email, handle);
    	if("true".equals(flog)){
    		return ResultData.mobileResult(1,"Successfully Handle the Concern",null);
    	}else if("false".equals(flog)){
    		return ResultData.mobileResult(0,"Failed Handle the Concern",null);
    	}else{
    		return ResultData.mobileResult(1009,"The Person Already in Your List",null);
    	}
    	
    }
    
    /**
     * 取消关注
     * @param token
     * @param email
     * @param type
     * @return
     */
    @RequestMapping(value = "/cancel",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject cancelConcern(@RequestParam String token ,@RequestParam String email ,@RequestParam String type){
    	
    	//type:myConcer 取消我的关注，concernMe，取消关注我的
    	logger.info("取消关注的对象:{}",email);
    	boolean flog = userInfoService.cancelConcern(token, email, type);
    	if(flog){
    		return ResultData.mobileResult(1,"Successfully Cancel the Concern",null);
    	}else{
    		return ResultData.mobileResult(0,"Failed Cancel the Concern",null);
    	}
    }
    
    /**
     * 获取待批准信息
     * @param token
     * @return
     */
    @RequestMapping(value = "/getWait",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject getWait(@RequestParam String token){
    	List list = userInfoService.getWait(token);
    	if(list == null){
    		return ResultData.mobileResult(0,"Server error",null);
    	}
    	return ResultData.mobileResult(1,"Successfully get the Info",list);
    }
    
    /**
     * 获取我的关注信息
     * @param token
     * @return
     */
    @RequestMapping(value = "/getMyConcern",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject getMyConcern(@RequestParam String token){
    	List list = userInfoService.getMyConcern(token);
    	if(list == null){
    		return ResultData.mobileResult(0,"Server error",null);
    	}
    	return ResultData.mobileResult(1,"Successfully get the Info",list);
    }
    
    /**
     * 获取关注我的信息
     * @param token
     * @return
     */
    @RequestMapping(value = "/getConcernMe",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject getConcernMe(@RequestParam String token){
    	List list = userInfoService.getConcernMe(token);
    	if(list == null){
    		return ResultData.mobileResult(0,"Server error",null);
    	}
    	return ResultData.mobileResult(1,"Successfully get the Info",JSONObject.toJSON(list));
    }
    
    /**
     * 外部模块使用 通过token来获取信息
     * @param token
     * @return
     */
    @RequestMapping(value = "/getUserIdByToken",method = RequestMethod.POST)
    @ResponseBody
    public JSONObject getUserIdByToken(@RequestParam String token){
    	long userId = 0;
    	try{
    		userId = (Long) redisUtil.get(token);
    	}catch(Exception e){
    		logger.info("getInfoByToken,CastException");
    		return null;
    	}
    	return ResultData.mobileResult(1,"Successfully get the Info",userId);
    }
}
